package org.sninwo.lnbook.book.service;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;

import org.sninwo.lnbook.base.Page;
import org.sninwo.lnbook.uitls.LangUtils;
import org.sninwo.lnbook.uitls.WebUtils;
import org.springframework.stereotype.Component;

import com.sun.image.codec.jpeg.JPEGCodec;

@Component
public class PhotoManager {
	//图片库的保存路径
	public static final String BOOK_PHOTO_PATH = "resources/book-photos/";
	//允许的图片文件后缀
	public static final String[] BOOK_PHOTO_EXTS = {"jpg","jpeg","bmp","gif","png","tif"};
	
	public static final String MIN_PHOTO_FOLDER_NAME = "min";
	/**
	 * 分页取出指定目录要显示的图片
	 */
	public Page<Map<String, Object>> getPageListInFolder(Page<Map<String, Object>> page, int folderIndex){
		File curFolder = getCurFolder(folderIndex);
		if (curFolder == null)
			return page;
		//目录的所有图片
		String[] allPhotos = getAllPhotosInFolder(curFolder);
		page.setTotalItems(allPhotos.length); //总数
		//图片分页
		List<Map<String,Object>> curPhotos = new ArrayList<Map<String,Object>>();
		for (int i = page.getStartRow() - 1; i < page.getEndRow() && i < allPhotos.length; i ++){
			Map<String, Object> item = new HashMap<String, Object>(2);
			String fileName = allPhotos[i];
			item.put("fileName", fileName);
			//去掉序号和后缀名做为图片的标题
			item.put("text", fileName.substring(fileName.indexOf('-') + 1, fileName.lastIndexOf('.'))); 
			curPhotos.add(item);
		}
		page.setResult(curPhotos);
		
		return page;
	}
	
	/**
	 * 取得要显示的图片目录列表，去掉目录序号，添加图片总数
	 */
	public List<Map<String, Object>> getFoldersToShow(){
		List<Map<String, Object>> foldersToShow = new ArrayList<Map<String, Object>>();
		List<File> folders = getAllFolders();
		for (File f : folders){
			Map<String, Object> folder = new HashMap<String, Object>(2);
			int i = f.getName().indexOf('-');
			String folderName = f.getName().substring(i + 1).trim();
			folder.put("folderName", folderName);
			folder.put("photoCount", getAllPhotosInFolder(f).length);
			foldersToShow.add(folder);
		}
		return foldersToShow;
	}
	
	/**
	 * 根据目录序号和图上名称获取图片
	 */
	public FileInputStream getPhoto(int folderIndex, String photoName) throws Exception{
		File curFolder = getCurFolder(folderIndex);
		if (curFolder == null){
			return null;
		}
		
		String path = curFolder.getAbsolutePath() + File.separator + photoName;
		return new FileInputStream(path);
	}

	/**
	 * 根据目录序号和图上名称获取图片的缩略图，如果没有缩略图上则生成。
	 */
	public FileInputStream getMinPhoto(int folderIndex, String photoName) throws Exception{
		File curFolder = getCurFolder(folderIndex);
		if (curFolder == null){
			return null;
		}
		
		String path = curFolder.getAbsolutePath() + File.separator + MIN_PHOTO_FOLDER_NAME + File.separator + photoName;
		File file = new File(path);
		if (!file.exists()){
			if (!file.getParentFile().exists())
				file.getParentFile().mkdir();
			int width = 200; //压缩后的图片宽度
			File srcFile = new File(curFolder.getAbsolutePath() + File.separator + photoName);
			BufferedImage srcImg = ImageIO.read(srcFile);
			int height = srcImg.getHeight() * width / srcImg.getWidth();
			BufferedImage tarImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			tarImg.getGraphics().drawImage(srcImg, 0, 0, width, height, null);
			//输出图片到文件
			FileOutputStream fileOut = new FileOutputStream(file);
			JPEGCodec.createJPEGEncoder(fileOut).encode(tarImg);
			fileOut.close();
		}
		return new FileInputStream(path);
	}
	
	private String[] getAllPhotosInFolder(File folder){
		return folder.list(new FilenameFilter(){
			public boolean accept(File dir, String name){
				String ext = name.substring(name.lastIndexOf('.') + 1).toLowerCase();
				return LangUtils.contains(BOOK_PHOTO_EXTS, ext);
			}
		});
	}
	
	private File getCurFolder(int folderIndex){
		List<File> allFolders = getAllFolders();
		if (folderIndex >= 0 && folderIndex < allFolders.size())
			return allFolders.get(folderIndex);
		else
			return null;
	}
	
	private List<File> getAllFolders(){
		List<File> folders = new ArrayList<File>();
		File baseDir = getBaseDir();
		if (!baseDir.exists()) baseDir.mkdirs();
		for (File f : baseDir.listFiles()){
			if (f.isDirectory()){
				folders.add(f);
			}
		}
		return folders;
	}
	
	private File getBaseDir(){
		File baseDir = new File(WebUtils.getRealPath(BOOK_PHOTO_PATH));
		if (!baseDir.exists()) baseDir.mkdirs();
		return baseDir;
	}
}
